home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / pcx_c.zip / PCX.C < prev    next >
C/C++ Source or Header  |  1988-04-17  |  11KB  |  479 lines

  1. /*    PCX.c -  Graphic Routines that operate on PCX pictures
  2. */
  3.  
  4.  
  5. #include <stdio.h>
  6. #include "lib.h"
  7. #include "pcx.h"
  8.  
  9.  
  10. int pcx_init();
  11. int pcx_clear();
  12. int pcx_set_point();
  13. int pcx_clr_point();
  14. int pcx_xor_point();
  15. int pcx_write_row();
  16. int pcx_select_plane();
  17. int pcx_set_palette();
  18. int pcx_mode();
  19. int movmem();
  20. int pokeb();
  21. int peekb();
  22. int pcx_get_point();
  23.  
  24. static int (*pcx_func[])() = {
  25.     pcx_init,      pcx_clear,     pcx_set_point, pcx_clr_point,
  26.     pcx_xor_point, pcx_get_point, pcx_write_row, pcx_select_plane,
  27.     pcx_set_palette,pcx_mode,     movmem, peekb, pokeb };
  28.  
  29. PCXPIC *pcx_cpic;      /* current picture   */
  30. static int cplane;     /* current plane     */
  31. int    pcx_md;        /* 1 if CGA-type picture, 0 for HERC/EGA */
  32.  
  33.  
  34. int pcx_init()
  35. {
  36.     movmem( pcx_func, vgr_func, sizeof(vgr_func) );
  37.  
  38.     VGR_NBPL = VGR_HRES = VGR_VRES = VGR_NCOLORS = cplane = 0;
  39.     if ( pcx_cpic )
  40.     {  VGR_HRES    = pcx_cpic->hdr.hres;
  41.        VGR_VRES    = pcx_cpic->hdr.vres;
  42.        VGR_NBPL    = pcx_cpic->hdr.bpl;
  43.        VGR_NCOLORS = pcx_cpic->hdr.bpp > 1 ? 
  44.                      0x01 << pcx_cpic->hdr.bpp :
  45.                      0x01 << pcx_cpic->hdr.nplanes;
  46.     };
  47.  
  48.     return OK;
  49. }
  50.  
  51.  
  52. int pcx_select_plane( plane )
  53. int plane;
  54. {
  55.     return cplane = plane & 0x03;
  56. }
  57.  
  58.  
  59. int pcx_write_row( row, prow, nbytes )
  60. int nbytes, row;
  61. char *prow;
  62. {
  63.     int i;
  64.  
  65.     i = pcx_cpic->hdr.hres / 8;
  66.     movmem( prow, (pcx_cpic->rows[cplane][row]), 
  67.                    nbytes <= i ? nbytes : i );
  68. }
  69.  
  70.  
  71. int pcx_clear()
  72. {
  73.     int plane, row, nplanes, nrows, bytes;
  74.  
  75.     nplanes =  pcx_cpic->hdr.nplanes;
  76.     nrows   =  pcx_cpic->hdr.y2 - pcx_cpic->hdr.y1 +1;
  77.     bytes   =  pcx_cpic->hdr.bpl;
  78.  
  79.     for ( plane=0; plane < nplanes; plane ++ )
  80.        for ( row=0; row < bytes; row++ )
  81.           setmem( (pcx_cpic->rows[plane][row]), bytes, 0 );
  82. }
  83.  
  84.  
  85. int pcx_mode( m )
  86. int m;
  87. {
  88.     switch ( m )
  89.     {  case MODE_APA0:   /* 640x350x16 */
  90.        case MODE_APA1:   /* 720x348x02 */
  91.        case MODE_APA2:   /* 640x200x02 */
  92.           /* all these modes save color information
  93.              1 bit per plane.
  94.           */
  95.           pcx_md = 0;
  96.           break;
  97.        case MODE_APA3:   /* 320x200x04 */
  98.           /* this mode puts two bits per pixel into the
  99.              same plane.
  100.           */
  101.           pcx_md = 1;
  102.           break;
  103.        default:          /* invalid!   */
  104.           return ERROR;
  105.     };
  106.  
  107.     return OK;
  108. }
  109.  
  110.  
  111. int pcx_xor_point( x, y, color )
  112. int x, y, color;
  113. {
  114.     return pcx_set_point( x, y, pcx_get_point( x, y ) ^ color );
  115. }
  116.  
  117.  
  118. int pcx_clr_point( x, y )
  119. int x, y;
  120. {
  121.     return pcx_set_point( x, y, 0 );
  122. }
  123.  
  124.  
  125. int pcx_set_point( x, y, color )
  126. int x, y, color;
  127. {
  128.     register unsigned char *p;
  129.     unsigned char plane, b, o, mask;
  130.  
  131.     if ( pcx_md )
  132.     {  o = (x & 3) << 1;
  133.        p = (unsigned char *)pcx_cpic->rows[0][y] + (x>>2);
  134.        *p = (*p & ~(0xc0 >> o)) | ((color & 0x03) << (6-o));
  135.        return OK;
  136.     };
  137.  
  138.     o = x >> 3;
  139.     b = (unsigned int)0x80 >> (x & 0x07);
  140.  
  141.     for ( mask=1,plane=0; plane < pcx_cpic->hdr.nplanes; plane++, mask<<=1 )
  142.     {  p = (unsigned char *)pcx_cpic->rows[plane][y] + o;
  143.        if ( color & mask )
  144.           *p |= b;
  145.        else *p &= ~b;
  146.     };
  147.  
  148.     return OK;
  149. }
  150.  
  151.  
  152. int pcx_get_point( x, y )
  153. int x, y;
  154. {
  155.     unsigned char plane, b, o, color;
  156.  
  157.     if ( pcx_md )
  158.     {  b = (x & 3) << 1;
  159.        return ( pcx_cpic->rows[0][y][x>>2] & (0xc0 >> b) ) >> (6-b);
  160.     };
  161.  
  162.     o = x >> 3;
  163.     b = (unsigned int)0x80 >> (x & 0x07);
  164.  
  165.     for ( color=plane=0; plane < pcx_cpic->hdr.nplanes; plane++ )
  166.        color |= !!(pcx_cpic->rows[plane][y][o] & b) << plane;
  167.  
  168.     return color;
  169. }
  170.  
  171.  
  172. /*    PCX Palette Settings.
  173. */
  174.  
  175. int pcx_set_palette( reg, red, green, blue )
  176. unsigned char reg, red, green, blue;
  177. {
  178.     if ( pcx_md )
  179.     {  pcx_cpic->hdr.triple[reg].red = red;
  180.        return OK;
  181.     };
  182.  
  183.     /* why do we multiply by 85? */
  184.     pcx_cpic->hdr.triple[reg].red   = red   * 85;
  185.     pcx_cpic->hdr.triple[reg].green = green * 85;
  186.     pcx_cpic->hdr.triple[reg].blue  = blue  * 85;
  187.     return OK;
  188. }
  189.  
  190.  
  191. PCXPIC *pcx_init_pic( hres, vres, nplanes )
  192. unsigned int hres, vres, nplanes;
  193. {
  194.     int y, p, bpl;
  195.     PCXPIC *pic;
  196.     char *calloc();
  197.     static TRIPLET ega_pal[] = {  /* copied from a        */
  198.           0x00, 0x00, 0x00,       /* PBRUSH picture file  */
  199.           0x00, 0x00, 0xaa,
  200.           0x00, 0xaa, 0x00,
  201.           0x00, 0xaa, 0xaa,
  202.           0xaa, 0x00, 0x00,
  203.           0xaa, 0x00, 0xaa,
  204.           0xaa, 0xaa, 0x00,
  205.           0xaa, 0xaa, 0xaa,
  206.           0x55, 0x55, 0x55,
  207.           0x55, 0x55, 0xff,
  208.           0x55, 0xff, 0x55,
  209.           0x55, 0xff, 0xff,
  210.           0xff, 0x55, 0x55,
  211.           0xff, 0x55, 0xff,
  212.           0xff, 0xff, 0x55,
  213.           0xff, 0xff, 0xff        };
  214.  
  215.     static TRIPLET cga_pal[] = {
  216.             0,0,0, 255,0,0,
  217.             0,0,0, 255,0,0,
  218.             0,0,0, 255,0,0,
  219.             0,0,0, 255,0,0,
  220.             0,0,0, 255,0,0,
  221.             0,0,0, 255,0,0,
  222.             0,0,0, 255,0,0,
  223.             0,0,0, 255,0,0        };
  224.  
  225.     if ( !(pic = (PCXPIC *) calloc( 1, sizeof(PCXPIC) )) )
  226.        return NULL; /* out of memory */
  227.  
  228.     pic->hdr.x2 = hres -1;
  229.     pic->hdr.y2 = vres -1;
  230.  
  231.     pic->hdr.maker     = 10;
  232.     pic->hdr.version   =  5;
  233.     pic->hdr.code      =  1;
  234.     pic->hdr.bpp       =  1 + pcx_md;
  235.     pic->hdr.bpl       = bpl = (hres * (1+pcx_md)) / 8;
  236.  
  237.     VGR_HRES    = pic->hdr.hres    = hres;
  238.     VGR_VRES    = pic->hdr.vres    = vres;
  239.     VGR_NBPL    = bpl;
  240.     VGR_NCOLORS = 1 << (pic->hdr.nplanes = nplanes);
  241.  
  242.     movmem( (pcx_md ? cga_pal : ega_pal), 
  243.              pic->hdr.triple, sizeof(pic->hdr.triple) );
  244.  
  245.     for ( p=0; p < nplanes; p++ )
  246.     {  if ( ! (pic->rows[p] = (uchar **)calloc( 1, sizeof(char *) * vres)) )
  247.           return pcx_free_pic( pic ), (PCXPIC *)0;
  248.        for ( y=0; y < vres; y++ )
  249.           if ( !(pic->rows[p][y] = (uchar *)calloc( 1, bpl )) )
  250.              return pcx_free_pic( pic ), (PCXPIC *)0;
  251.     };
  252.  
  253.     return pic;
  254. }
  255.  
  256.  
  257. int pcx_free_pic( pic )
  258. PCXPIC *pic;
  259. {
  260.     int row, plane, nrows, nplan;
  261.  
  262.     nrows = pic->hdr.y2 - pic->hdr.y1 +1;
  263.     nplan = pic->hdr.nplanes;
  264.  
  265.     VGR_MODE( MODE_TEXT0 );
  266.     printf("At pcx_free_pic, probably out of memory...\n");
  267.  
  268.     for ( plane = 0; plane < nplan; plane++ )
  269.     {  for ( row = 0; row < nrows; row++ )
  270.           allocf( pic->rows[plane][row] );
  271.        allocf( pic->rows[plane] );
  272.     };
  273.  
  274.     allocf( pic );
  275.     return NULL;
  276. }
  277.  
  278.  
  279. void map_not( map, len )
  280. register unsigned int *map, len;
  281. {
  282.     for ( ; len--; map++ )
  283.        *map = ~ *map;
  284. }
  285.  
  286.  
  287. void pcx_invert_pic( pic )
  288. PCXPIC *pic;
  289. {
  290.     int p, r, i;
  291.  
  292.     for ( p=0; p < pic->hdr.nplanes; p++ )
  293.        for ( r=0; r < (pic->hdr.y2 - pic->hdr.y1); r++ )
  294.           map_not( pic->rows[p][r], pic->hdr.bpl / 2 );
  295. }
  296.  
  297.  
  298. allocf( p )
  299. char *p;
  300. {
  301.     if ( !p )
  302.        return OK;
  303.  
  304.     if ( free(p) == -1 )
  305.        CRASH( "heap munged" );
  306. }
  307.  
  308. #ifdef MAIN
  309.  
  310. /*    Manx 'C stack/heap size adjustment -
  311.     The vgr_fill() function uses an enourmous amount of stack,
  312.     and we're going to need enough heap space to allocate
  313.     4 bit maps for the EGA board.
  314. */
  315. uint    __STKLOW = 0,
  316.         __STKSIZ = 4096,
  317.         __HEAPSIZ = 8192;
  318.  
  319. int     cga_init(), ega_init(), herc_init();
  320. int    board, (*board_init)(), md;
  321.  
  322. /*    This structure is used here to facilitate drawing the
  323.     simple X and complex box that are used to test the
  324.     dot, line and fill functions.
  325. */
  326. typedef struct {
  327.    int x,y;
  328. } OBJ;
  329.  
  330. static OBJ obj[] = { 
  331. 100, 100, 150, 200, 200, 100, 250, 150, 175, 250, 250, 350, 200, 400, 150, 300, 
  332. 100, 400,  50, 350, 125, 250,  50, 150, 100, 100 };
  333.  
  334. static OBJ obj2[] = {
  335.   0,  0,280,  0,280,140,240,140,240, 20,200, 20,200,280,240,280,240,160, 
  336. 280,160,280,300,  0,300,  0,160, 40,160, 40,280, 80,280, 80, 20, 40, 20, 
  337.  40,140,  0,140,  0,  0 };
  338.        
  339. static OBJ obj3[] = {
  340.        120,20, 160,20, 160,280, 120,280, 120,20 };
  341.  
  342.  
  343. main( argc, argv )
  344. char **argv;
  345. int argc;
  346. {
  347.     void pcx_showpic();
  348.     FILE *fp, *fopen();
  349.     int c, h, v, p;
  350.  
  351.     printf("PCX test routine.\n");
  352.     if ( argc == 1 )
  353.        printf("Try \"PCX xx\" for help\n" );
  354.  
  355.     board = vgr_get_board();
  356.  
  357.     if ( argc >= 2 )
  358.     {       if ( !strcmp(argv[1], "ega") )
  359.                board = TYPE_EGA;
  360.        else if ( !strcmp(argv[1], "cga") )
  361.                board = TYPE_CGA;
  362.        else if ( !strcmp(argv[1], "herc") )
  363.                board = TYPE_HERC;
  364.        else if ( !strcmp(argv[1], "cga2") )
  365.                board = 9;
  366.        else {  printf("